import java.awt.*; // This library includes the graphics functions
import java.applet.Applet; // This library is needed for applets
import java.awt.event.*; // This library is needed for event handling
public class Star extends Applet implements Runnable
{
// This creates the variable starThread of type Thread
// using threads allows for different tasks to happen
// at the same time.
Thread starThread;
// The variable out is used as a flag as to whether or not the
// mouse cursor is in the game.
// if out = 1 then the game is paused
public int out = 0;
// The following variables are used obvious
public boolean gameover = false;
public int kills = 0;
public int health = 100;
// This variable modifies how long the explosion sprite should be displayed
public int deathWait = 12;
// These three variable are used to determine the random time between
// enemies appearing
public int randomSeed = 50;
public int randomTime = (int) (((Math.random() * randomSeed) + 1) + 50);
public int timeInc = 0;
// These arrays are used to hold varius data concerning the enemies
// These could be grouped into a single object
public int enemyX[];
public int enemyY[];
public int enemySpeed[];
public int enemyOpen[];
public int enemyType[];
public int enemyDeath[];
public int enemySlope[];
// These arrays contain data about the bullets being fired from the ship
// again they could be grouped into a single object
public int bX[];
public int bY[];
public int bOpen[];
public int bType[];
public int numBullets = 20;
public int numStars = 30;
public int bulletShot = 0;
// These are for the star field
public int starsX[];
public int starsY[];
// These can modify the screen size
public int xSize = 640, ySize = 480;
// These variables can be changed to speed up or slow down the game
public int speed = 6;
public int sleepTime = 16;
// These are the coordinates for the space ship
public int shipX = (xSize / 2) - 17;
public int shipY = ySize - 80;
// This is used for image buffering
Image imageBuffer;
// These variables hold the images for the game
Image ship;
Image enemy1;
Image enemy2;
Image ex;
Image b1;
Image b2;
// This method initializes the some of the variables to be use in the game
public void init()
{
setSize(xSize, ySize);
enemyX = new int[5]; // The number 5 indicates that there are 5 enemies
// that are going to be cycled through
enemyY = new int[5];
enemySpeed = new int[5];
enemyOpen = new int[5];
enemyType = new int[5];
enemyDeath = new int[5];
enemySlope = new int[5];
bX = new int[numBullets];
bY = new int[numBullets];
bOpen = new int[numBullets];
bType = new int[numBullets];
ship = getImage(getCodeBase(), "ship.gif"); // This is how easy it is to
// load a graphic
enemy1 = getImage(getCodeBase(), "enemy1.gif");
enemy2 = getImage(getCodeBase(), "enemy2.gif");
ex = getImage(getCodeBase(), "ex.gif");
b1 = getImage(getCodeBase(), "b1.gif");
b2 = getImage(getCodeBase(), "b2.gif");
initStars();
repaint();
addMouseListener(new LocalMouseListener(this));
addMouseMotionListener(new LocalMouseMotionListener(this));
}
// When the applet starts the thread starts!
public void start()
{
if(starThread == null)
{
starThread = new Thread(this);
starThread.setPriority(5);
starThread.start();
}
}
// When the applet stops the thread stops!
public void stop()
{
if(starThread != null)
{
starThread.stop();
starThread = null;
}
}
// This will create a new enemy to scroll down the screen
// Again there are only really 5 enemies that are cycled through
// then enemyOpen[] array determines whether an enemy is currently "alive"
public void newEnemy()
{
int r = 0;
for(int a = 0; a < 5; a++)
{
if(r == 0 & enemyOpen[a] == 0)
{
enemyOpen[a] = 1;
r = 1;
enemySpeed[a] = (int) ((Math.random() * 5) + 1);
enemyType[a] = (int) ((Math.random() * 2) + 1);
enemySlope[a] = (int) (((Math.random() * 3) + 1) - 1);
int t = (int) ((Math.random() * 2) + 1);
if(t == 1)
{
enemySlope[a] = -(enemySlope[a]);
}
enemyX[a] = (int) ((Math.random() * (xSize - 32)) + 1);
enemyY[a] = -32;
randomTime = (int) (((Math.random() * randomSeed) + 1) + 50);
timeInc = 0;
}
}
}
// This is the heart of the program
// It runs over and over again while the thread is active and the program is
// going!
public void run()
{
while(true)
{
if(health == 0)
{
kills = 0;
health = 100;
gameover = true;
}
timeInc++; // This will call the newEnemy method if a random time
// has elapsed for a new enemy to appear
if(timeInc == randomTime)
{
newEnemy();
}
moveEnemys(); // These methods update the sprites positions
moveStars();
moveBullets();
collisions();
prepareImageBuffer(); // This method prepares the screen to be drawn
repaint(); // This draws the graphics to the screen
try
{ // This pauses the game
starThread.sleep(sleepTime);
}
catch(InterruptedException e)
{
}
}
}
// This creates the starfield in the background
public void initStars()
{
imageBuffer = createImage(xSize, ySize);
starsX = new int[numStars];
starsY = new int[numStars];
for(int a = 0; a < numStars; a++)
{
starsX[a] = (int) ((Math.random() * xSize - 1) + 1);
starsY[a] = (int) ((Math.random() * ySize - 1) + 1);
}
}
// This method moves the enemies
public void moveEnemys()
{
for(int i = 0; i < 5; i++)
{
if(enemyX[i] + enemySlope[i] < 0)
{ // These statements move the enemies haphazardly left and right
enemySlope[i] *= -1;
}
if(enemyX[i] + enemySlope[i] > xSize - 32)
{
enemySlope[i] *= -1;
}
enemyX[i] += enemySlope[i];
int a = (int) ((Math.random() * 150) + 1);
if(a == 3)
{
enemySlope[i] *= -1;
}
if(a == 5 & Math.abs(enemySlope[i]) < 8)
{
enemySlope[i] *= -2;
}
if(a == 6 & Math.abs(enemySlope[i]) > 0)
{
enemySlope[i] /= -2;
}
if(enemyOpen[i] > 0)
{
if(enemyOpen[i] == 2)
{
if(enemyDeath[i] == deathWait)
{
enemyOpen[i] = 0;
}
else
{
enemyDeath[i]++;
}
}
if(enemyY[i] > ySize)
{
enemyOpen[i] = 0;
}
else
{
enemyY[i] += enemySpeed[i] + (speed - 6); // This moves the
// enemy down
}
}
}
}
// This method simply tests for collisions between the sprites on the screen
public void collisions()
{
if(out == 0)
{
for(int i = 0; i < 5; i++)
{
// Tests for collission between bullet and player ship
for(int a = 0; a < numBullets; a++)
{
if(bOpen[a] == 1)
{
if(bY[a] > shipY & bY[a] < shipY + 32)
{
if(bX[a] > shipX & bX[a] < shipX + 32)
{
bOpen[a] = 0;
health -= 5;
}
}
}
// Tests for collision between bullets and enemy ships
if(bOpen[a] == 1 & enemyOpen[i] == 1)
{
if(bY[a] > enemyY[i] & bY[a] < enemyY[i] + 32)
{
if(bX[a] > enemyX[i] & bX[a] < enemyX[i] + 32)
{
enemyDeath[i] = 0;
enemyOpen[i] = 2;
bOpen[a] = 0;
kills++;
}
}
}
}
// Tests for colision between enemy and player ship
if(enemyOpen[i] == 1)
{
if((shipX + 32 > enemyX[i]) & (shipX < enemyX[i] + 32))
{
if((shipY + 32 > enemyY[i]) & (shipY < enemyY[i] + 36))
{
enemyDeath[i] = 0;
enemyOpen[i] = 2;
health -= 5;
}
}
}
}
}
}
// If a bullet has been fired this will move it
public void moveBullets()
{
for(int i = 0; i < numBullets; i++)
{
if(bOpen[i] == 1)
{
if(bY[i] < 5)
{
bOpen[i] = 0;
}
else
{
if(bType[i] == 1)
{
bY[i] -= 2;
}
else
{
bY[i] -= 4;
}
}
}
}
}
// If a star in the background reaches the bottome then it will go back to
// the top
public void moveStars()
{
for(int a = 0; a < numStars; a++)
{
if(starsY[a] + 1 > ySize - (speed * 2))
{
starsY[a] = 0;
}
else
{
starsY[a] += speed;
}
}
}
// This prepares the graphics to being drawn to the screen
public void prepareImageBuffer()
{
Graphics g = imageBuffer.getGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, xSize, ySize);
g.setColor(Color.blue);
for(int a = 0; a < numStars; a++)
{
g.drawRect(starsX[a], starsY[a], 1, 1);
}
g.setColor(Color.yellow);
g.drawString("Kills = " + kills, 5, 20);
g.drawString("Health = " + health + "%", xSize - 80, 20);
if(out == 0)
{
if(gameover == true)
{
g.drawString("Game Over", (xSize / 2) - 15, ySize / 2);
}
}
else
{
g.drawString("Game Paused", (xSize / 2) - 23, ySize / 2);
}
g.setXORMode(Color.black); // This allows sprites to preserve the
// background
for(int q = 0; q < numBullets; q++)
{
if(bOpen[q] == 1)
{
if(bType[q] == 1)
{
g.drawImage(b1, bX[q] - (b1.getWidth(this) / 2), bY[q] - b1.getHeight(this), this);
}
else
{
g.drawImage(b2, bX[q] - (b1.getWidth(this) / 2), bY[q] - b1.getHeight(this), this);
}
}
}
for(int i = 0; i < 5; i++)
{
if(enemyOpen[i] == 2)
{
g.drawImage(ex, enemyX[i], enemyY[i], this);
}
if(enemyOpen[i] == 1)
{
if(enemyType[i] == 1)
{
g.drawImage(enemy1, enemyX[i], enemyY[i], this);
}
else
{
g.drawImage(enemy2, enemyX[i], enemyY[i], this);
}
}
}
g.drawImage(ship, shipX, shipY, this);
}
// This draws the graphics to the screen
public void paint(Graphics g)
{
g.drawImage(imageBuffer, 0, 0, this);
}
// This overides the update method for smooth animation
public void update(Graphics g)
{
paint(g);
}
// This class listens for the mouse to be moved or dragged
// when the mouse is dragged than a bullet is fired!
// Also, when shift is held down then the ship goes wherever the mouse goes.
// If alt is held down than a different bullet is fired!
class LocalMouseMotionListener implements MouseMotionListener
{
Star parent;
LocalMouseMotionListener(Star p)
{
parent = p;
}
public void mouseDragged(MouseEvent e)
{
int r = 0;
if(bulletShot == 4)
{
if(gameover == true)
{
gameover = false;
}
for(int a = 0; a < numBullets; a++)
{
if(bOpen[a] == 0 & r == 0)
{
if(e.isAltDown() == true)
{
bType[a] = 2;
}
else
{
bType[a] = 1;
}
bX[a] = shipX + 16;
bY[a] = shipY - 1;
bOpen[a] = 1;
r = 1;
}
}
bulletShot = 0;
}
else
{
bulletShot++;
}
int xx = e.getX();
int yy = e.getY();
if(yy < shipY - 32)
{
speed = 9;
}
else
{
speed = 6;
}
if(e.isShiftDown() == true)
{
if(yy < ySize & yy > 100)
{
shipY = yy - 16;
}
}
if(xx < xSize & xx > 1)
{
shipX = xx - 16;
}
}
public void mouseMoved(MouseEvent e)
{
int xx = e.getX();
int yy = e.getY();
if(yy < shipY - 32)
{
speed = 9;
}
else
{
speed = 6;
}
if(e.isShiftDown() == true)
{
if(yy < ySize & yy > 100)
{
shipY = yy - 16;
}
}
if(xx < xSize & xx > 1)
{
shipX = xx - 16;
}
}
}
// This class handles mouse clicking and whether or not the mouse is in the
// game!
// Again if alt is down a different bullet is fired.
// I trap for all events that involve clicking and releasing the mouse
// button to ensure that the bullet is fired.
class LocalMouseListener implements MouseListener
{
Star parent;
LocalMouseListener(Star p)
{
parent = p;
}
public void mouseClicked(MouseEvent e)
{
int r = 0;
if(gameover == true)
{
gameover = false;
}
for(int a = 0; a < numBullets; a++)
{
if(bOpen[a] == 0 & r == 0)
{
if(e.isAltDown() == true)
{
bType[a] = 2;
}
else
{
bType[a] = 1;
}
bX[a] = shipX + 16;
bY[a] = shipY - 1;
bOpen[a] = 1;
r = 1;
}
}
}
public void mouseReleased(MouseEvent e)
{
int r = 0;
if(gameover == true)
{
gameover = false;
}
for(int a = 0; a < numBullets; a++)
{
if(bOpen[a] == 0 & r == 0)
{
if(e.isAltDown() == true)
{
bType[a] = 2;
}
else
{
bType[a] = 1;
}
bX[a] = shipX + 16;
bY[a] = shipY - 1;
bOpen[a] = 1;
r = 1;
}
}
}
public void mouseEntered(MouseEvent e)
{
out = 0;
}
public void mouseExited(MouseEvent e)
{
out = 1;
}
public void mousePressed(MouseEvent e)
{
int r = 0;
if(gameover == true)
{
gameover = false;
}
for(int a = 0; a < numBullets; a++)
{
if(bOpen[a] == 0 & r == 0)
{
if(e.isAltDown() == true)
{
bType[a] = 2;
}
else
{
bType[a] = 1;
}
bX[a] = shipX + 16;
bY[a] = shipY - 1;
bOpen[a] = 1;
r = 1;
}
}
}
}
}